import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;

import cn.accp.bookshop.Book;
import cn.accp.bookshop.MyStack;

public class Test {

	public static void main(String[] args) {
		demo25();
	}

	/**
	 * 集合： 数组 int[]arr=new int[10] 相同类型数据的一堆数的组合。使用索引访问里面的每个元素，使用两种方式来遍历。
	 * 数组的典型用法：查找，求极值，删除，插入... 这些功能都需要我们编程，特别是插入，删除。麻烦
	 * 还有一个限制，长度是已经定义，是固定的，不能动态改变。 不方便，功能薄弱 =========== java给我们提供了集合，来代替数组。
	 * java给的集合框架 Collection 接口 Map接口 List Set 子接口 HashMap 实现类 ArrayList
	 * LinkedList HashSet 实现类 Collection 提供对集合的访问操作（） indexOf() int 查找
	 * add(Object obj) 添加 remove() 删除 contains() 判断是否存在 size() 集合里有多少元素 List 和
	 * Set List接口是有序的，里面的元素不唯一，增加了一套 支持索引访问的方法。 Set接口是简单的按照散列存放，所以，是无序，唯一。
	 * List接口的实现类 ArrayList 内部实现机制，原理类似ArrayBookDao,数组。 LinkedList 学习 List接口
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static void demo1() {
		List list = new ArrayList();// 默认长度
		// 方法的参数是Object，集合里可以添加Object类型的元素，所有的对象都可以放入
		Book book = new Book(1, "c++", 22);
		list.add(book);// 添加一个元素
		list.add(new Book(1002, "java", 28));// 添加一个元素
		list.add(new Book(3, "mysql", 32));// 添加一个元素
		list.add(2, new Book(4, "html", 20));// 插入，在第2个位置插入对象。
		list.add(book);// 添加一个重复的元素会如何呢？ m没问题，不唯一
		// 开始遍历下
		System.out.println("第一种，按索引遍历");
		// size()方法获得元素的个数
		// get(index) 获得第Index处元素
		Book b = null;
		// 注意，理解，book指向的这个对象，目前有3个引用指向,哪三个呢？ book
		// list集合的第0个元素，以及最后一个元素。
		book.setTitle("c++编程");
		for (int i = 0; i < list.size(); i++) {
			b = (Book) list.get(i);// 如果你添加的时候，如果类型错误，不是添加的book，这里会产生类型转换失败异常
			System.out.println(b.toString());
		}
		System.out.println("第二种，增强for循环遍历");
		for (Object object : list) {
			b = (Book) object;
			System.out.println(b.toString());
		}
		// 集合框架给了我们第三种遍历方式，就是用迭代器接口 Iterator
		// 如何理解迭代器接口
		/*
		 * iterator------>刚打开，迭代器，指向了集合的第零个元素的上一个 [0][1][2][3][4]5[]
		 * iterator.hasNext()检测有没有下一个元素iterator.next() 取出下一个元素，并返回，同时移到下一个位置
		 * iterator------> [0][1][2][3][4] iterator------> [0][1][2][3][4]
		 * iterator------> [0][1][2][3][4] iterator------> [0][1][2][3][4]
		 */
		System.out.println("第三种，使用迭代器循环遍历");
		Iterator iterator = list.iterator();// 返回迭代器对象
		while (iterator.hasNext()) {
			b = (Book) iterator.next();
			System.out.println(b.toString());
		}
		// /////////////////////////////////////////////////
		// 演示查找
		System.out.println("book这个元素索引位置:" + list.indexOf(book));
		// /////////////////////////
		// 上课练习： 在list这个图书集合里，查找图书编号为3的图书，找到显示图书信息和所在的位置
		int index = -1;
		for (int i = 0; i < list.size(); i++) {
			b = (Book) list.get(i);
			if (b.getId() == 3) {
				index = i;
				break;
			}
		}
		if (index == -1) {
			System.out.println("不存在");
		} else {
			System.out.println(b.toString() + "位置在" + index);
		}
		// /////////////////////////////////////////////////////
		// 删除 remove
		// 删除指定索引位置的元素，返回被删的
		// 删除对象
		list.remove(book);
		//
		System.out.println("显示删除索引位置2的图书信息");
		for (Object object : list) {
			b = (Book) object;
			System.out.println(b.toString());
		}

	}

	/**
	 * 集合典型应用之，求最大值
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static void demo1_1() {
		List list = new ArrayList();// 默认长度
		// 方法的参数是Object，集合里可以添加Object类型的元素，所有的对象都可以放入
		Book book = new Book(1, "c++", 22);
		list.add(book);// 添加一个元素
		list.add(new Book(1002, "java", 28));// 添加一个元素
		list.add(new Book(3, "mysql", 32));// 添加一个元素
		list.add(2, new Book(4, "html", 20));// 插入，在第2个位置插入对象。
		// 求出单价最高的书的对象
		double max = 0;
		int maxIndex = -1;
		Book b;
		for (int i = 0; i < list.size(); i++) {
			b = (Book) list.get(i);
			if (b.getPrice() > maxIndex) {
				max = b.getPrice();
				maxIndex = i;
			}
		}
		b = (Book) list.get(maxIndex);// 得到单价最贵的那本书
		System.out.println(b.toString() + "\t在位置" + maxIndex);
		Iterator iterator = list.iterator();// 返回迭代器对象
		while (iterator.hasNext()) {
			b = (Book) iterator.next();
			System.out.println(b.toString());
		}

	}

	@SuppressWarnings("unchecked")
	public static void demo1_2() {
		@SuppressWarnings("rawtypes")
		List list = new ArrayList();// 默认长度
		// 方法的参数是Object，集合里可以添加Object类型的元素，所有的对象都可以放入
		Book book = new Book(1, "c++", 22);
		list.add(book);// 添加一个元素
		list.add(new Book(2, "java", 78));// 添加一个元素
		list.add(new Book(3, "mysql", 32));// 添加一个元素
		list.add(new Book(4, "html", 20));
		list.add(new Book(5, "css", 48));
		// 删除单价超过30元的图书
		Book b;
		for (int i = 0; i < list.size(); i++) {
			b = (Book) list.get(i);
			if (b.getPrice() > 30) {
				list.remove(i);
				i--;// 因为，删除一个元素后，size()总数是会减一的，所以，这里i要回退。
			}
		}
		System.out.println("显示删除后的结果");
		Iterator iterator = list.iterator();// 返回迭代器对象
		while (iterator.hasNext()) {
			b = (Book) iterator.next();
			System.out.println(b.toString());
		}

	}

	/**
	 * LinkedList实现类? ArrayList 和LinkedList的区别
	 * ArrayList内部是用数组来实现的，那么存取速度快,遍历块，插入和删除性能低 LinkedList内部是链表机制 [ 数据部分 A |
	 * 下个元素的地址next B001 ] B001 [ B | F001 ] C001 [C | null ] 好处插入很高效 F001[F |
	 * C001 ] ======== 删除B元素 插入和删除很高效，但是遍历慢。
	 */
	public static void demo2() {
		// LinkedList 添加了独立，对头尾元素的直接访问
		// 书本第七页，表格
		List list = new LinkedList();// 默认长度
		// 方法的参数是Object，集合里可以添加Object类型的元素，所有的对象都可以放入
		Book book = new Book(1, "c++", 22);
		list.add(book);// 添加一个元素
		list.add(new Book(1002, "java", 28));// 添加一个元素
		list.add(new Book(3, "mysql", 32));// 添加一个元素
		list.add(2, new Book(4, "html", 20));// 插入，在第2个位置插入对象。
		list.add(book);// 添加一个重复的元素会如何呢？ m没问题，不唯一
		// 开始遍历下
		System.out.println("第一种，按索引遍历");
		// size()方法获得元素的个数
		// get(index) 获得第Index处元素
		Book b = null;
		// 注意，理解，book指向的这个对象，目前有3个引用指向,哪三个呢？ book
		// list集合的第0个元素，以及最后一个元素。
		book.setTitle("c++编程");
		for (int i = 0; i < list.size(); i++) {
			b = (Book) list.get(i);// 如果你添加的时候，如果类型错误，不是添加的book，这里会产生类型转换失败异常
			System.out.println(b.toString());
		}
		System.out.println("第二种，增强for循环遍历");
		for (Object object : list) {
			b = (Book) object;
			System.out.println(b.toString());
		}
		// 集合框架给了我们第三种遍历方式，就是用迭代器接口 Iterator
		// 如何理解迭代器接口
		/*
		 * iterator------>刚打开，迭代器，指向了集合的第零个元素的上一个 [0][1][2][3][4]5[]
		 * iterator.hasNext()检测有没有下一个元素iterator.next() 取出下一个元素，并返回，同时移到下一个位置
		 * iterator------> [0][1][2][3][4] iterator------> [0][1][2][3][4]
		 * iterator------> [0][1][2][3][4] iterator------> [0][1][2][3][4]
		 */
		System.out.println("第三种，使用迭代器循环遍历");
		Iterator iterator = list.iterator();// 返回迭代器对象
		while (iterator.hasNext()) {
			b = (Book) iterator.next();
			System.out.println(b.toString());
		}
		// /////////////////////////////////////////////////
		// 演示查找
		System.out.println("book这个元素索引位置:" + list.indexOf(book));
		// /////////////////////////
		// 上课练习： 在list这个图书集合里，查找图书编号为3的图书，找到显示图书信息和所在的位置
		int index = -1;
		for (int i = 0; i < list.size(); i++) {
			b = (Book) list.get(i);
			if (b.getId() == 3) {
				index = i;
				break;
			}
		}
		if (index == -1) {
			System.out.println("不存在");
		} else {
			System.out.println(b.toString() + "位置在" + index);
		}
		// /////////////////////////////////////////////////////
		// 删除 remove
		// 删除指定索引位置的元素，返回被删的
		// 删除对象
		list.remove(book);
		//
		System.out.println("显示删除索引位置2的图书信息");
		for (Object object : list) {
			b = (Book) object;
			System.out.println(b.toString());
		}
		// //////////////////////////////////////
		// 操作下LinkedList个性化的方法 对头尾的操作
		LinkedList books = (LinkedList) list;
		books.addFirst(new Book(10, "java高级", 88));
	}

	/**
	 * set接口,实现类 HashSet 无序，而且唯一。 既然是无序，所有ArrayList中凡是带索引的方法，这里一律不支持。
	 * ArrayList中带索引的 get() ，remove(int index), add(int index, Object obj)
	 */
	public static void demo3() {
		Set list = new HashSet();// 默认长度
		// 方法的参数是Object，集合里可以添加Object类型的元素，所有的对象都可以放入
		Book book = new Book(1, "c++", 22);
		list.add(book);// 添加一个元素
		list.add(new Book(2, "java", 78));// 添加一个元素
		list.add(new Book(3, "mysql", 32));// 添加一个元素
		list.add(new Book(4, "html", 20));
		list.add(new Book(5, "css", 48));
		list.add(book);// 重复添加失败

		Book b;
		System.out.println("第一种，增强for循环遍历");
		// 看到显示的效果，发现，id是和添加进去的顺序不一样。体会set接口就是无序的。
		for (Object object : list) {
			b = (Book) object;
			System.out.println(b.toString());
		}

		System.out.println("第二种，使用迭代器循环遍历");
		Iterator iterator = list.iterator();// 返回迭代器对象
		while (iterator.hasNext()) {
			b = (Book) iterator.next();
			System.out.println(b.toString());
		}

	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static void demo3_1() {
		Set list = new HashSet();// 默认长度
		// 方法的参数是Object，集合里可以添加Object类型的元素，所有的对象都可以放入
		Book book = new Book(1, "c++", 22);
		list.add(book);// 添加一个元素
		list.add(new Book(2, "java", 78));// 添加一个元素
		list.add(new Book(3, "mysql", 32));// 添加一个元素
		list.add(new Book(4, "html", 20));
		list.add(new Book(5, "css", 48));
		// 查找单价最贵的那本书，显示图书信息
		// 求出单价最高的书的对象
		double max = 0;
		Book maxBook = null;
		Book b = null;
		for (Object object : list) {
			b = (Book) object;
			if (b.getPrice() > max) {
				maxBook = b;
				max = b.getPrice();
			}
		}
		System.out.println("最贵图书信息：" + maxBook.toString());
		Iterator iterator = list.iterator();// 返回迭代器对象
		while (iterator.hasNext()) {
			b = (Book) iterator.next();
			System.out.println(b.toString());
		}

	}

	/**
	 * Map接口，集合两大接口， Collection和Map Collection下有两个子接口 List,Set
	 * 所以，Map和之前的List，Set 浑身不搭界。所以，之前List里的这些方法都不能用，都不同。 Map这个集合非常像我们使用的字典 中文字典：
	 * 字---- 解释 字是唯一的，通过字取查解释， key 字 解释 值 value key,value都是集合，一个key对应一个value
	 * key可以重复么？唯一，不重复。set就是唯一不重复 value 可以重复，List集合。 Map就是key-value集合。
	 */
	@SuppressWarnings("unchecked")
	public static void demo4() {
		@SuppressWarnings("rawtypes")
		Map list = new HashMap();
		Book book = new Book(1, "c++", 22);
		list.put("a01", book);// 添加一个元素
		list.put("a02", new Book(2, "java", 78));// 添加一个元素
		list.put("a03", new Book(3, "mysql", 32));// 添加一个元素
		list.put("a04", book);
		list.put("a05", new Book(5, "css", 48));
		list.put("a05", new Book(6, "css2", 58));
		// 当添加时，如果key重复，那么 会覆盖值，新的value覆盖旧的
		// 当添加是，value重复，那么 允许，没问题
		// 遍历思路，可以单独遍历key集合. 也可以单独遍历值集合。
		// 或 遍历key集合，通过key去操作值
		Set set = list.keySet();// 获得这个map里的key集合
		Book b;
		for (Object key : set) {
			b = (Book) list.get(key);// 通过key获得对应值，Book对象，所以要强转
			System.out.println("key=" + key.toString() + "\t" + b.toString());
		}
		// 删除 key=a02
		list.remove("a02");
		System.out.println("显示删除后的结果");
		for (Object key : set) {
			b = (Book) list.get(key);// 通过key获得对应值，Book对象，所以要强转
			System.out.println("key=" + key.toString() + "\t" + b.toString());
		}

	}

	/**
	 * 学会泛型集合 之前的集合，存在弊端，因为添加的时候，类型是Object，这样，任何对象都可以添加，那么很容易出错。
	 * 另外，使用时，会比较麻烦，需要类型的强转。 ============ 为了更好的解决上面的弊端，java给我们提供了第二套集合框架，即泛型集合。
	 * 好处：定义集合时，就已经指定了添加到集合里的类型，如果添加类型错误，就会报错。 还有，使用时，再也无须进行繁琐的类型转换了。
	 * 无需再重新学习，新版本和老版本完全一致。
	 */
	public static void demo5() {
		// 定义集合对象，泛型集合，指定，添加到这个集合里的对象，都是Book类型
		List<Book> list = new ArrayList<Book>();// 默认长度
		Book book = new Book(1, "c++", 22);
		list.add(book);// 添加一个元素
		list.add(new Book(1002, "java", 28));// 添加一个元素
		list.add(new Book(3, "mysql", 32));// 添加一个元素
		list.add(2, new Book(4, "html", 20));// 插入，在第2个位置插入对象。
		list.add(book);// 添加一个重复的元素会如何呢？ m没问题，不唯一
		// 开始遍历下
		System.out.println("第一种，按索引遍历");

		Book b = null;
		book.setTitle("c++编程");
		for (int i = 0; i < list.size(); i++) {
			b = list.get(i);
			System.out.println(b.toString());
		}
		System.out.println("第二种，增强for循环遍历");
		for (Book object : list) {
			System.out.println(object.toString());
		}
		System.out.println("第三种，使用迭代器循环遍历");
		Iterator<Book> iterator = list.iterator();// 返回迭代器对象
		while (iterator.hasNext()) {
			b = iterator.next();
			System.out.println(b.toString());
		}
		// /////////////////////////////////////////////////
		// 演示查找
		System.out.println("book这个元素索引位置:" + list.indexOf(book));
		// /////////////////////////
		// 上课练习： 在list这个图书集合里，查找图书编号为3的图书，找到显示图书信息和所在的位置
		int index = -1;
		for (int i = 0; i < list.size(); i++) {
			b = list.get(i);
			if (b.getId() == 3) {
				index = i;
				break;
			}
		}
		if (index == -1) {
			System.out.println("不存在");
		} else {
			System.out.println(b.toString() + "位置在" + index);
		}
		// /////////////////////////////////////////////////////
		// 删除 remove
		// 删除指定索引位置的元素，返回被删的
		// 删除对象
		list.remove(book);
		//
		System.out.println("显示删除索引位置2的图书信息");
		for (Book object : list) {
			System.out.println(object.toString());
		}
	}

	/**
	 * Set<T>
	 */
	public static void demo6() {
		// 泛型Set
		Set<Book> list = new HashSet<Book>();// 默认长度
		// 方法的参数是Object，集合里可以添加Object类型的元素，所有的对象都可以放入
		Book book = new Book(1, "c++", 22);
		list.add(book);// 添加一个元素
		list.add(new Book(2, "java", 78));// 添加一个元素
		list.add(new Book(3, "mysql", 32));// 添加一个元素
		list.add(new Book(4, "html", 20));
		list.add(new Book(5, "css", 48));
		list.add(book);// 重复添加失败

		Book b;
		System.out.println("第一种，增强for循环遍历");
		// 看到显示的效果，发现，id是和添加进去的顺序不一样。体会set接口就是无序的。
		for (Book object : list) {
			System.out.println(object.toString());
		}

		System.out.println("第二种，使用迭代器循环遍历");
		Iterator<Book> iterator = list.iterator();// 返回迭代器对象
		while (iterator.hasNext()) {
			b = iterator.next();
			System.out.println(b.toString());
		}

	}

	/**
	 * 泛型Map
	 */
	public static void demo7() {
		// 定义时，指定Key的类型是String Value的类型是Book
		Map<String, Book> list = new HashMap<String, Book>();
		Book book = new Book(1, "c++", 22);
		list.put("a01", book);// 添加一个元素
		list.put("a02", new Book(2, "java", 78));// 添加一个元素
		list.put("a03", new Book(3, "mysql", 32));// 添加一个元素
		list.put("a04", book);
		list.put("a05", new Book(5, "css", 48));
		list.put("a05", new Book(6, "css2", 58));
		// 当添加时，如果key重复，那么 会覆盖值，新的value覆盖旧的
		// 当添加是，value重复，那么 允许，没问题
		// 遍历思路，可以单独遍历key集合. 也可以单独遍历值集合。
		// 或 遍历key集合，通过key去操作值
		Set<String> set = list.keySet();// 获得这个map里的key集合
		Book b;
		for (String key : set) {
			b = list.get(key);// 通过key获得对应值，Book对象，所以要强转
			System.out.println("key=" + key.toString() + "\t" + b.toString());
		}
		// 删除 key=a02
		list.remove("a02");
		System.out.println("显示删除后的结果");
		for (String key : set) {
			b = list.get(key);// 通过key获得对应值，Book对象，所以要强转
			System.out.println("key=" + key.toString() + "\t" + b.toString());
		}

	}

	/**
	 * 自定义泛型类呢？ 实现一个泛型集合，实现栈的功能: 栈：是一种结构，这种结构，具备先进后出，后进先出。 MyStack +size() int
	 * +push(obj) 入栈 +pop() 出 +iterator()
	 */
	public static void demo8() {
		MyStack<Book> list = new MyStack<Book>();
		list.push(new Book(1, "c++", 22));
		list.push(new Book(2, "java", 78));
		list.push(new Book(3, "html", 78));
		System.out.println("遍历下栈集合里，有哪些元素");
		Iterator<Book> iterator = list.iterator();
		while (iterator.hasNext()) {
			System.out.println(iterator.next().toString());
		}
		Book book = list.pop();// 出栈
		System.out.println("出栈的图书信息:" + book.toString());
		System.out.println("出栈后遍历下栈集合里，有哪些元素");
		iterator = list.iterator();
		while (iterator.hasNext()) {
			System.out.println(iterator.next().toString());
		}
	}

	public static void demo9() {
		Stack<Book> list = new Stack<Book>();
		list.push(new Book(1, "c++", 22));
		list.push(new Book(2, "java", 78));
		list.push(new Book(3, "html", 78));
		System.out.println("遍历下栈集合里，有哪些元素");
		Iterator<Book> iterator = list.iterator();
		while (iterator.hasNext()) {
			System.out.println(iterator.next().toString());
		}
		Book book = list.pop();// 出栈
		System.out.println("出栈的图书信息:" + book.toString());
		System.out.println("出栈后遍历下栈集合里，有哪些元素");
		iterator = list.iterator();
		while (iterator.hasNext()) {
			System.out.println(iterator.next().toString());
		}
	}

	/**
	 * 队这个结构 Queue 队的结构是： 排队 先进先出，后进后出 MyStack +size() int +enQueue(obj) 入队
	 * +deQueue() 出队 +iterator()
	 * 
	 */

	// /////////////////////////////
	// 第二章，实用类
	/**
	 * 枚举类型 Enum, 是值类型 为什么要用这个类型： 订单状态， 0 未处理、1 已确认、2 已发货、3 确认收货、4 拒收退货、5 会员撤单、
	 * 6管理员撤单 int flag;//订单状态 这种解决方案，是硬编码，不直观，使用麻烦，而且很容易出错， 赋值9 如何改变这种情况？
	 * 使用软编码的方式，用预先设定好的常量值来代替。 Enum 这就是枚举类型的使用场景。 一般开发时，如果是两状态， true,false
	 * 3态以上，偷懒做法是硬编码，建议使用软编码。
	 */
	public static void demo10() {
		Order order = new Order(1, "张三", OrderState.UNCHECK);
		OrderState state = OrderState.COMPLETED; // 像普通变量一样使用
		if (state == OrderState.COMPLETED) {
			System.out.println("订单状态为已完成");
		}
		switch (order.getOrderState()) {
		case UNCHECK:
			System.out.println("订单未确认，可以取消");
			break;
		case CHECKED:
			System.out.println("订单已确认，处理中");
			break;
		case SENDED:
			System.out.println("订单已发货");
			break;
		case COMPLETED:
			System.out.println("订单已完成");
			break;
		case ROLLBACK:
			System.out.println("订单已拒收");
			break;
		case USERCANCELORDER:
			System.out.println("会员已撤单");
			break;
		case ADMINCANCELORDER:
			System.out.println("管理员已撤单");
			break;
		default:
			break;
		}

	}

	/**
	 * 包装类的概念 java中的值类型， int short long,double ,char,float,boolean ，
	 * 有很多地方是需要使用对象的，类的，引用类型，不能值类型？ 如果想用集合，来放值类型？不行，必须要用引用类型。 那怎么办？
	 * 好在，java为每个值类型都配对一个包装类 31页表 int --Integer char -Character double -Double
	 * float -Float 总结下：包装类的使用场景 一般，能够用值类型的，用值类型，因为快，高效。 必须要用的，那就用，如集合。 包装类的静态方法
	 * 最常用的就是类型转 如 Integer.parseInt() Double.parseDouble()
	 */
	public static void demo11() {
		// 第一种方式
		Integer integer1 = new Integer(100);
		// 将值类型赋值给包装类，实际上， java做了类型转换， 术语装箱
		Integer integer2 = 100;
		Integer integer3 = Integer.valueOf(123);// 使用包装类的静态方法
		// 有了包装类，那么就可以使用集合了
		List<Integer> nums = new ArrayList<Integer>();
		nums.add(integer1);
		nums.add(20);
		int x = integer1.intValue();// 获得里面的值
		int y = integer1;// 直接将应用类型赋值给值类型, 术语，拆箱
		System.out.println("y=" + y);
		// 包装类提供了一些静态方法和属性，供我们使用
		// Integer.MAX_VALUE int的最大容量
		// parseXXX
		// 类型转换的方法
		String string = "12345";// 字符串
		int num = Integer.parseInt(string);
		System.out.println("num=" + num);
	}

	/**
	 * Math数学类的使用
	 */
	public static void demo12() {
		System.out.println("25的平方根:" + Math.sqrt(25));
		System.out.println("2的5次方:" + Math.pow(2, 5));
		System.out.println("floor向下取整" + (int) Math.floor(18.98));
		System.out.println("四舍五入" + (int) Math.round(18.98));
		System.out.println("随机0-100,random 0-1之间的小数:"
				+ (int) (Math.random() * 100));
	}

	/**
	 * 操作字符串 String length() int 长度 charAt(int index) char 返回某个索引位置的字符
	 * indexOf(String str) int 查询，存在索引，不存在-1 lastIndexOf() int 同上，从右开始查匹配的第一个
	 * substring(int start,int end) Stirng 截取字符串 toUpperCase() 转大写
	 * toLowerCase()转小写 trim()去除两端空格 replace(String search,String rpt)
	 * 将seach替换成rpt split(String ch) String[] 切割 contains(String s)是否包含s
	 */
	public static void demo13() {
		String string = "abcde";
		System.out.println("方法 length()，求长度" + string.length());
		System.out.println("charAt:" + string.charAt(2));
		System.out.println("indexOf查找" + string.indexOf("zz"));
		String filename = "abc.jpg";// 取出扩展名
		String ext = filename.substring(filename.lastIndexOf('.') + 1);// 从后面的字符截取到最后
		System.out.println(ext);
		System.out.println(ext.toUpperCase().toLowerCase());
		String s1 = "  abc    ";
		System.out.println(s1.trim().length());
		s1 = "aa*bb*cc*dd*aa*ff";
		System.out.println(s1.replace('*', '+'));
		System.out.println(s1.replace("aa", "AA"));
		String s2 = "窗前明月光，疑是地上霜，举头王明月，低头思故乡";
		String[] parts = s2.split("，");
		for (String string2 : parts) {
			System.out.println(string2);
		}
		System.out.println(checkEmail("abc@163.com.cn"));

		// String.format()是拼接字符串的好工具
		// String.format("%d+%d=%d",1,2,3); 1+2=3
		// 占位符号 %d 整数 %m.nf小数 %s 字符串 %c 字符
		int d1 = 123;
		double d2 = 67.5;
		char d3 = 'z';
		String d4 = "abcdef";
		System.out.println(String.format("d1=%d,d2=%5.2f,d3=%c,d4=%s", d1, d2,
				d3, d4));
	}

	/**
	 * 检查传入的mail是否是合格的电子邮件格式 1.收尾字符不能是 @ 或 . 2. 只有一个 @ 3. 只有1-2个. 4. 不存在 @.
	 * 这样的字符串
	 * 
	 * @param mail
	 * @return
	 */
	public static boolean checkEmail(String mail) {
		// 1.收尾字符不能是 @ 或 .
		char first = mail.charAt(0);// 首字符
		char last = mail.charAt(mail.length() - 1);// 得到尾字符
		if (first == '@' || first == '.' || last == '@' || last == '.') {
			return false;
		}
		// 2. 只有一个 @
		// 从左查 从右查 一样，但不能为-1
		if (mail.indexOf("@") != mail.lastIndexOf("@")) {
			return false;
		}
		// 判断. 只能1到2个。 可以使用split切割，如果一个点数组长度2，两个点 3.
		// 如果是敏感字符 . 这就是 敏感字符 \\.
		String[] parts = mail.split("\\.");
		// 只需判断切割后数组的长度不为2或3.
		if (parts.length < 2 || parts.length > 3) {
			return false;
		}
		// 只需查找 @.是否存在 contains(s) boolean
		if (mail.contains("@.") == true) {
			return false;
		}
		return true;
	}

	/**
	 * 传入 一个url网址，带查询字符串的 如 abc.jsp?id=3&name=abc abc.jsp?name=bbb
	 * 
	 * @param url
	 *            带查询字符串的网址
	 * @param key
	 *            要查的关键字 如id或者 name
	 * @return 返回key对应的值 此例中 如key是id则返回3 key是name则返回abc
	 */
	public static String request(String url, String key) {
		return null;
	}

	/**
	 * 理解 String StringBuffer 和StringBuilder的差异点
	 */
	public static void demo14() {
		// 下面是在解释，字符串==和equals之间的差异点
		String s1 = "abc";// 字符串常量
		String s2 = "abc";
		String s3 = new String("abc");// 在堆里开辟一个空间，里面放的是abc
		// 字符串的==，其实是在判断地址是否相同 s1里放的是"abc"这个字符串在常量区的地址
		System.out.println(s1 == s2);
		System.out.println(s1 == s3);
		// 所以，你希望判断字符串的内容是否相同，那么使用 equals方法
		System.out.println(s1.equals(s3));
		// /////////////////////////////////////////////////////
		// 提问，下面的代码，共产生了多少个对象？
		// 1 5 6 4 5
		// "a" "b" "c" "d" "e" "ab" "abc" "abcd" "abcde"
		// 字符串常量拼接，每次都会产生一个新的字符串常量。
		// 如果我们程序中需要用到大量的字符串拼接，那么如下方式对性能太差了。
		String a1 = "a";
		a1 += "b";
		a1 += "c";
		a1 += "d";
		a1 += "e";
		String a2 = "abcde";
		System.out.println(a1 == a2);
		System.out.println(a1);
		// 改进的方案，系统StringBuffer
		// 在堆区开辟一个对象，构造方法把a, 每次append，是这个对象里的字符串变ab abc abcd abcde
		// 不会产生 多余的字符串行列对象。所以，性能提高。所以，如果大量的字符串拼接那么使用本对象
		StringBuffer stringBuffer = new StringBuffer("a");
		stringBuffer.append("b");
		stringBuffer.append("c");
		stringBuffer.append("d");
		stringBuffer.append("e");
		// StringBuffer和StringBuilder的区别 书本44页
		// StringBuffer线程安全，非StringBuilder是单线程的，不同步，理论上效率高。
		System.out.println(convertBooks());
	}

	/**
	 * 将这个图书集合，拼接成如下格式的字符串，并返回
	 * 
	 * @return <books> <book id="1"> <name>c++</name> <price>23</name> </book>
	 *         <book id="2"> <name>java</name> <price>22</name> </book> </books>
	 */
	public static String convertBooks() {
		List<Book> list = new ArrayList<Book>();
		Book book = new Book(1, "c++", 22);
		list.add(book);// 添加一个元素
		list.add(new Book(2, "java", 78));// 添加一个元素
		list.add(new Book(3, "mysql", 32));// 添加一个元素
		list.add(new Book(4, "html", 20));
		list.add(new Book(5, "css", 48));
		StringBuffer xml = new StringBuffer("<books>");
		for (Book book2 : list) {
			// \" 表示"
			// xml.append("\n\t<book id=\""+book2.getId()+"\">");
			// String.format()是拼接字符串的好工具
			// String.format("%d+%d=%d",1,2,3); 1+2=3
			// 占位符号 %d 整数 %f小数 %s 字符串 %c 字符
			xml.append(String.format("\n\t<book id=\"%d\">", book2.getId()));
			xml.append(String.format("\n\t\t<name>%s</name>", book2.getTitle()));
			xml.append("\n\t\t<price>" + book2.getPrice() + "</price>");
			xml.append("\n\t</book>");
		}
		xml.append("\n</books>");
		return xml.toString();
	}

	/**
	 * 日期对象的使用 Date Calendar
	 */
	public static void demo15() {
		Date date = new Date();// 获得一个当前日期对象
		// 想显示下日期,可以借助一个类 SimpleDateFormat
		// 注意，yyyy表示年份 MM月份 dd日期 HH小时 mm分钟 ss秒数
		DateFormat dft = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
		System.out.println(dft.format(date));// 显示下
		// Date里的方法，很多都被否决了，如getYear() 所以，推荐使用Calendar类。
		// 简单用无所谓，只是日期，显示
		Calendar calendar = Calendar.getInstance();// 得到一个当前日期对象
		// 可以获取内部的年月日等日期部分
		String string = String.format(
				"%d-%d-%d %d:%d:%d %d",
				calendar.get(Calendar.YEAR),
				calendar.get(Calendar.MONTH) + 1,// 月份从零开始，所以加1
				calendar.get(Calendar.DATE), calendar.get(Calendar.HOUR),
				calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND),
				calendar.get(Calendar.MILLISECOND));
		System.out.println(string);
		Date date2 = calendar.getTime();// 返回Date类型
		System.out.println(dft.format(date2));// 显示下
		// 设置日期
		Calendar calendar2 = Calendar.getInstance();
		calendar2.set(2016, 4, 8);
		System.out.println(dft.format(calendar2.getTime()));
		// ////////////////////////////////////////////////
		// 有时也会做日期之间的比较
		// 比如，会员下了一个订单，后台管理界面，显示 下单时间 1小时23分
		Calendar c1 = Calendar.getInstance();
		c1.set(2018, 8, 5, 9, 23, 33);// 当时的下单时间
		Calendar c2 = Calendar.getInstance();// 当前时间
		// 求出c1和c2之间，差了多少分钟？
		// getTimeInMillis()获取从基准日期到现在的毫秒值
		long ret = c2.getTimeInMillis() - c1.getTimeInMillis();// 这是这两个日期之间差的毫秒值
		long minute = ret / 1000 / 60;// 将毫秒值转成分钟
		System.out.println(minute);
		System.out.println(String.format("%d小时%d分钟", minute / 60, minute % 60));
		int aa = 10;
		System.out.println(String.format("a=%d", c1.get(Calendar.YEAR) - aa));
		// 要求显示 1小时23分
	}

	/**
	 * 测试下，回家作业里的JsonHelper
	 */
	public static void demo16() {
		List<Book> list = new ArrayList<Book>();
		Book book = new Book(1, "c++", 22);
		list.add(book);// 添加一个元素
		list.add(new Book(2, "java", 78));// 添加一个元素
		list.add(new Book(3, "mysql", 32));// 添加一个元素
		list.add(new Book(4, "html", 20));
		list.add(new Book(5, "css", 48));
		String jsonString = BookJSONHelper.toJson(list);
		System.out.println(jsonString);
		String string = BookJSONHelper.toJson(book);
		Book book2 = BookJSONHelper.toBook(string);
		System.out.println(book2.toString());

	}

	/**
	 * 文件操作 判断某个文件是否存在，读取文件信息，文件名，路径，长度等 文件：文本文件和了二进制文件 创建文件，写入文件，保存
	 * 读取文件，读取到内存，关闭 System.io 包 input &output
	 */
	public static void demo17() {
		// 操作文件或目录属性
		File file = new File("d:\\a.txt");
		// 判断文件或路径是否存在
		if (file.exists() == false) {
			try {
				file.createNewFile();
				System.out.println("文件创建成功!");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				System.out.println("文件创建失败!");
				e.printStackTrace();
			}// 创建文件或路径
		}
		// 显示文件/路径信息
		System.out.println("文件绝对路径：" + file.getAbsolutePath());
		System.out.println("最后修改日期" + file.lastModified());
		System.out.println("文件名:" + file.getName());
		System.out.println("文件长度" + file.length() + "字节");
	}

	/**
	 * 文件读写， 文本文件读写 理解一个文件流
	 * 
	 * 文件源---------> 内存 读取的过程，input InputStream,Reader作为基类 内存----------->文件
	 * 保存，存盘，output OutStream Writer 写文本文件 Writer
	 */
	public static void demo18() {
		File file = new File("d:\\a.txt");
		Writer writer = null;// 写入对象
		String content = "床前明月光\n疑是地上霜\n举头望明月\n低头思故乡";
		try {
			writer = new FileWriter(file);// 实例化文件写
			writer.write(content);// 把这个字符串写入文件里
			System.out.println("写入成功！！！");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			System.out.println("文件不存在！！！");
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("写入失败");
			e.printStackTrace();
		} finally {
			try {
				if (writer != null) {
					writer.flush();// 将缓冲区里的内容，真正写文件,刷新输入流
					writer.close();// 关闭
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	/**
	 * 将上面写的这个文件读取出来
	 */
	public static void demo19() {
		File file = new File("d:\\a.txt");
		Reader reader = null;// 读取流对象
		StringBuffer stringBuffer = new StringBuffer();// 用来保存文件读取的字符
		try {
			reader = new FileReader(file);
			int ch = reader.read();// 读取文件的一个字符，把这个字符以 unicode码格式返回
			while (ch != -1) {
				// 读取成功
				stringBuffer.append((char) ch);// 添加到字符串里
				ch = reader.read();// 继续读取下一个
			}
			System.out.println(stringBuffer.toString());// 输出文件内容。
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			System.out.println("文件不存在！！！");
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("文件读取异常");
			e.printStackTrace();
		} finally {
			try {
				if (reader != null) {
					reader.close();
				}

			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	/**
	 * 使用BufferedReader 带缓冲的读 效率更高
	 */
	public static void demo20() {
		File file = new File("d:\\a.txt");
		Reader reader = null;// 读取流对象
		BufferedReader bReader = null;// 带缓冲区的读
		StringBuffer stringBuffer = new StringBuffer();// 用来保存文件读取的字符
		try {
			reader = new FileReader(file);
			bReader = new BufferedReader(reader);// 实例化
			String lineString = bReader.readLine();// 读取一行
			while (lineString != null) {
				// 读取成功
				stringBuffer.append(lineString + "\n");// 添加到字符串里
				lineString = bReader.readLine();// 读取一行//继续读取下一个
			}
			System.out.println(stringBuffer.toString());// 输出文件内容。
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			System.out.println("文件不存在！！！");
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("文件读取异常");
			e.printStackTrace();
		} finally {
			try {
				if (bReader != null) {
					bReader.close();
				}
				if (reader != null) {
					reader.close();
				}

			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	/**
	 * 二进制文件的读写 对程序员来说，文件 文本文件和二进制文件之分 文件copy 功能
	 * DataInputStream,DataOutputStream InputStream read() int DataInputStream
	 * readInt() int readDouble() double
	 */
	public static void demo21() {
		// copy文件的，思路
		String fileName1 = "d:\\a.jpg";
		String fileName2 = "d:\\b.jpg";
		// 复制a.jpg 到b.jpg,思路就是a文件打开读一个字节，写入b文件。 循环a读完，b也写完了。
		InputStream inputStream = null;// 输入流，读取
		OutputStream outputStream = null;// 输出流，写入
		File file2 = new File(fileName2);
		if (file2.exists() == true) {
			System.out.println("目标文件存在，不再COPY");
			return;
		} else {
			try {
				file2.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}// 创建文件
		}
		try {
			inputStream = new FileInputStream(fileName1);
			outputStream = new FileOutputStream(fileName2);
			int temp = inputStream.read();// 读取一个
			int count = 0;// 计数器，一行显示5个字符
			while (temp != -1) {
				// 读取成功,只是看看 格式是
				System.out.print(Integer.toHexString(temp) + "H(" + (char) temp
						+ ")\t");
				count++;
				if (count % 5 == 0) {
					System.out.println();
				}
				outputStream.write(temp);// 写文件
				temp = inputStream.read();// 读取下一个
			}
			System.out.println("复制完成！");

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				if (inputStream != null) {
					inputStream.close();
				}
				if (outputStream != null) {
					outputStream.close();
				}

			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	/**
	 * 写入二进制文件
	 */
	public static void demo22() {
		String fileName1 = "d:\\a.dat";
		OutputStream outStream = null;// 输出流，读取
		DataOutputStream dataOutputStream = null;// 二进制写入流
		try {
			outStream = new FileOutputStream(fileName1);
			dataOutputStream = new DataOutputStream(outStream);
			dataOutputStream.writeDouble(58.98);
			dataOutputStream.writeInt(100);
			System.out.println("二进制写入成功");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				if (dataOutputStream != null) {
					dataOutputStream.close();
				}
				if (outStream != null) {
					outStream.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}

	}

	/**
	 * 读取二进制文件
	 */
	public static void demo23() {
		String fileName1 = "d:\\a.dat";
		InputStream inStream = null;// 输出流，读取
		DataInputStream dataInputStream = null;// 二进制输出流
		try {
			inStream = new FileInputStream(fileName1);
			dataInputStream = new DataInputStream(inStream);
			double d1 = dataInputStream.readDouble();// 读取double
			int d2 = dataInputStream.readInt();// 读取int
			System.out.println("你写入的是" + d1 + "\t" + d2);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				if (dataInputStream != null) {
					dataInputStream.close();
				}
				if (inStream != null) {
					inStream.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}

	}

	/**
	 * 序列化和反序列化 我们有时需要把内存的对象保存。 如在游戏中，随时保存游戏，然后，开始游戏时，可以选择一个存盘点，继续游戏。
	 * 保存游戏，无外乎是保存的数据，如英雄对象，怪兽对象，关卡等等。 序列化，指将内存对象保存到物理文件里 反序列号：读取物理文件，恢复对象。
	 * 
	 * 如果一个类，能够被序列化，那么这个类必须实现 java.io.Serializble这个接口 ObjectOutputStream
	 * ObjectInputStream
	 */
	public static void demo24() {
		List<Book> list = new ArrayList<Book>();
		Book book = new Book(1, "c++", 22);
		list.add(book);// 添加一个元素
		list.add(new Book(2, "java", 78));// 添加一个元素
		list.add(new Book(3, "mysql", 32));// 添加一个元素
		list.add(new Book(4, "html", 20));
		list.add(new Book(5, "css", 48));
		// 将这个集合对象序列化
		OutputStream outputStream = null;
		ObjectOutputStream objectOutputStream = null;
		try {
			outputStream = new FileOutputStream("d:\\book.dat");
			objectOutputStream = new ObjectOutputStream(outputStream);
			objectOutputStream.writeObject(list);// 将对象写入到文件里
			System.out.println("序列化成功!");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			System.out.println("文件不存在");
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("写入错误");
			e.printStackTrace();
		} finally {
			try {
				if (objectOutputStream != null) {
					objectOutputStream.close();
				}
				if (outputStream != null) {
					outputStream.close();
				}

			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	/**
	 * 反序列化，就是加载序列化的文件，读取文件到对象
	 */
	public static void demo25() {
		List<Book> books;
		FileInputStream inputStream = null;// 输入流
		ObjectInputStream objectInputStream = null;
		try {
			inputStream = new FileInputStream("d:\\book.dat");
			objectInputStream = new ObjectInputStream(inputStream);
			books = (List<Book>) objectInputStream.readObject();// 读取对象，并类型转换
			for (Book book : books) {
				System.out.println(book.toString());
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			System.out.println("文件不存在");
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("文件读取失败");
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			System.out.println("类型转换失败");
			e.printStackTrace();
		} finally {
			try {
				if (objectInputStream != null) {
					objectInputStream.close();
				}
				if (inputStream != null) {
					inputStream.close();
				}

			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}

	}
}
